// emacs mode line -*- mode: c++; tab-width: 4 -*-
// this file defines the interfaces for all the type independent
// entities in the distributed array implementation
module msa
{
    // this is the per processor cache of pages.
    template<class ENTRY_TYPE, class ENTRY_OPS_CLASS,unsigned int ENTRIES_PER_PAGE> group MSA_CacheGroup
    {
        entry MSA_CacheGroup(unsigned int nPages, CkArrayID pageArrayID,
                         unsigned int max_bytes, unsigned int nEntries, unsigned int numberOfWorkerThreads);
        entry void AckPage(unsigned int page);
        entry void ReceivePage(unsigned int page, ENTRY_TYPE pageData[size], int size);
        entry void ReceivePageWithPUP(unsigned int page, const MSA_PageT<ENTRY_TYPE, ENTRY_OPS_CLASS, ENTRIES_PER_PAGE> &pageData, int size);
        entry void enroll();
        entry void enroll(unsigned int numberOfWorkerThreads);
        entry void enrollAck(int originator);  // internal method
        entry void enrollDone();  // internal method
        entry void SyncAck(bool clear);
        entry void SyncDone(CkReductionMsg *);

        // Push data to its home and wait for notice that everyone else has caught up
		entry [threaded] void FinishSync();

        // for debugging purposes only
        entry void emitBufferValue(int ID, unsigned int pageNum, unsigned int offset);
    };

    // this array is the storage for the pages. It in effect
    // virtualizes the storage for the pages
    template<class ENTRY_TYPE, class ENTRY_OPS_CLASS,unsigned int ENTRIES_PER_PAGE> array[1D] MSA_PageArray
    {
        entry MSA_PageArray(void);
	entry void setCacheProxy(const CProxy_MSA_CacheGroup<ENTRY_TYPE, ENTRY_OPS_CLASS, ENTRIES_PER_PAGE> &cache);
	
        entry void GetPage(int pe);
        entry void PAReceivePage(ENTRY_TYPE page[ENTRIES_PER_PAGE], int pe, MSA_Page_Fault_t pageState);
        entry void PAReceiveRLEPage(MSA_WriteSpan_t spans[nSpans], unsigned int nSpans, ENTRY_TYPE entries[nEntries], unsigned int nEntries, int pe, MSA_Page_Fault_t pageState);
        entry void PAReceiveRLEPageWithPup(MSA_WriteSpan_t spans[nSpans], unsigned int nSpans, const MSA_PageT<ENTRY_TYPE, ENTRY_OPS_CLASS, ENTRIES_PER_PAGE> &entries, unsigned int nEntries, int pe, MSA_Page_Fault_t pageState);
        entry void Sync(bool clear);
	
        // for debugging purposes only
        entry void emit(int ID, int offset);
    };
};
